﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WuYuHotel.SQLConn;
using System.Text;
using System.Data;
using WuYuHotel.Tools;
using System.Threading;


namespace WuYuHotel.WX_AccToken
{
    public class WXAccToken
    {
        //至专科技有限公司 服务号
        //AppID:wx8261af4dcdbe9479
        //AppSecret:94b327f0b2df0a7297ec53cf2adae212
        BaseDao basedao = new BaseDao();
        public Thread thread = null;
        //public BaseDao basedao=new BaseDao();

        /// <summary>
        /// 接收全局变量传过来的context
        /// </summary>
        public HttpContext context
        {
            get;
            set;
        }

        public  void TokenThread()
        {
            //string appid = "wx8261af4dcdbe9479";
            //string secret = "94b327f0b2df0a7297ec53cf2adae212";
            string appid = context.Application["appid"].ToString();
            string secret = context.Application["secret"].ToString();
            RandomStr RString = new RandomStr();

            BaseDao basedao = new BaseDao();
            while (true)
            {
                //把数据库里面的票据等取出来赋值
                string sql = "SELECT DATEDIFF(MINUTE, updateTime, GETDATE()) as diffTime,acc_Token,jsapi_ticket,noncestr,UNIXTime,api_ticket  from WxToken where WxTokenId=1";
                List<Dictionary<string, object>> list = basedao.GetList(sql, new string[] { "diffTime", "acc_Token", "jsapi_ticket", "noncestr", "UNIXTime","api_ticket" });
                context.Application["acc_Token"] = list[0]["acc_Token"].ToString();
                context.Application["jsapi_ticket"] = list[0]["jsapi_ticket"].ToString();
                context.Application["noncestr"] = list[0]["noncestr"].ToString();
                context.Application["UNIXTime"] = list[0]["UNIXTime"].ToString();
                context.Application["api_ticket"] = list[0]["api_ticket"].ToString();
                if (90 > int.Parse(list[0]["diffTime"].ToString()))
                {
                    //休息5分钟再去查
                    Thread.Sleep(60000 * 5);
                    continue;
                }


                string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret + "";
                HttpWebRequest req;
                HttpWebResponse resp;
                StreamReader sr;
                string fullhtml = null;
                try
                {
                    req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "GET";
                    req.KeepAlive = true;
                    req.Timeout = 30000;
                    req.ContentType = "application/json;encoding=utf-8";
                    resp = (HttpWebResponse)req.GetResponse();
                    if (resp.StatusCode != HttpStatusCode.OK) //如果服务器未响应，那么继续等待相应
                    {
                        Dictionary<string, object> datalog = new Dictionary<string, object>();
                        datalog.Add("type", int.Parse("2"));
                        datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        datalog.Add("OpID", "0");
                        datalog.Add("OpLog", "异常，获取服务器令牌盾时候，服务器没有返回200，返回值  " + resp.StatusCode.ToString());
                        basedao.save("T_LOG", datalog);
                        //req.Abort();
                        //resp.Close();
                        Thread.Sleep(5000);
                        continue;
                    }
                    sr = new StreamReader(resp.GetResponseStream(), Encoding.UTF8);
                    fullhtml = sr.ReadToEnd().Trim();
                }
                catch (WebException ex)
                {
                    ex.StackTrace.ToString();
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常，获取令牌时候抛出的catch :" + ex.Message.ToString().Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    Thread.Sleep(5000);
                    continue;
                }
                req.Abort();
                resp.Close();
                sr.Close();

                if (fullhtml.Contains("access_token"))
                {

                }
                else
                {
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常：微信获取令牌盾错误：" + fullhtml.Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    Thread.Sleep(5000);
                    continue;
                }
                string acc_Token = null;
                JToken json_AccToken = JToken.Parse(fullhtml);
                acc_Token = json_AccToken.Value<string>("access_token");
                context.Application["acc_Token"] = acc_Token;
                //到此为止，获取了access_token



                //下面是获取票据
                url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acc_Token + "&type=jsapi";
                fullhtml = null;
                try
                {
                    req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "GET";
                    req.KeepAlive = true;
                    req.Timeout = 30000;
                    req.ContentType = "application/json;encoding=utf-8";
                    resp = (HttpWebResponse)req.GetResponse();
                    if (resp.StatusCode != HttpStatusCode.OK) //如果服务器未响应，那么继续等待相应
                    {
                        Dictionary<string, object> datalog = new Dictionary<string, object>();
                        datalog.Add("type", int.Parse("2"));
                        datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        datalog.Add("OpID", "0");
                        datalog.Add("OpLog", "异常，jsapi_ticket时候，服务器没有返回200，返回值  " + resp.StatusCode.ToString());
                        basedao.save("T_LOG", datalog);
                        //req.Abort();
                        //resp.Close();
                        Thread.Sleep(5000);
                        continue;
                    }
                    sr = new StreamReader(resp.GetResponseStream(), Encoding.UTF8);
                    fullhtml = sr.ReadToEnd().Trim();
                }
                catch (WebException ex)
                {
                    ex.StackTrace.ToString();
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常，获取jsapi_ticket时候抛出的catch :" + ex.Message.ToString().Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    Thread.Sleep(5000);
                    continue;
                }
                req.Abort();
                resp.Close();
                sr.Close();
                //errcode
                if (fullhtml.Contains("errcode"))
                {

                }
                else
                {
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常：获取jsapi_ticket时候，服务器返回值不包含errcode，数据可能出错：" + fullhtml.Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    Thread.Sleep(5000);
                    continue;
                }
                string jsapi_ticket = null;
                int errcode;
                JToken json_JSTicket = JToken.Parse(fullhtml);
                errcode = json_JSTicket.Value<int>("errcode");
                if (errcode != 0)
                {
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常：获取jsapi_ticket时候，errcode!=0，" + fullhtml.Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    Thread.Sleep(5000);
                    continue;
                }
                jsapi_ticket = json_JSTicket.Value<string>("ticket");


                //下面获取卡卷的api_ticket
                url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acc_Token + "&type=wx_card";
                var client = new WebClient();
                client.Encoding = Encoding.UTF8;
                byte[] ResponseData = client.DownloadData(url);
                string SrcString = Encoding.UTF8.GetString(ResponseData);
                JObject jo = (JObject)JsonConvert.DeserializeObject(SrcString);
                string err_code = jo["errcode"].ToString();
                string ticket = jo["ticket"].ToString();
                //写到这里 下面需要判断正确性 和更新

                //这里生成随机16位字符串
                string noncestr = RString.GenerateCheckCode(16);
                //这里生成时间戳
                string UNIXTime = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString();
                //最后更新这3个基本的数据

                //把这个存到全局变量里面去
                context.Application["jsapi_ticket"] = jsapi_ticket;
                context.Application["noncestr"] = noncestr;
                context.Application["UNIXTime"] = UNIXTime;

                //这里WxToken里面，有且只有1条记录，所以这里直接用update全部即可
                sql = "update WxToken set acc_Token='" + acc_Token + "',jsapi_ticket='" + jsapi_ticket + "',noncestr='" + noncestr + "',UNIXTime='" 
                    + UNIXTime + "',updateTime='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "',api_ticket='"+ticket+"' where WxTokenId=1";
                try
                {
                    BaseDao.execute(sql);
                }
                catch (Exception ex)
                {
                    Dictionary<string, object> datalog = new Dictionary<string, object>();
                    datalog.Add("type", int.Parse("2"));
                    datalog.Add("OpTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    datalog.Add("OpID", "0");
                    datalog.Add("OpLog", "异常：记录token到数据库错误，" + ex.Message.ToString().Replace("'", "''").Replace(" ", ""));
                    basedao.save("T_LOG", datalog);
                    throw;
                }
                
                //90分钟刷新一次
                Thread.Sleep(60000 * 90);
            }




        }
    }
}